package simpleHttpClient;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * This class will establish a connection, send the request and make a response
 * to pass back up. Closing the socket after the operation is complete.
 * Defaulted port to 80
 * 
 * @author Scott Wendlandt
 * Rebecca Chandler
 * Li Weihan
 */
public class ClientServerConnection {

	/**
	 * The file location that this will be saved to.
	 */
	private File file = null;
	/**
	 * The socket that will used to establish a connection with the server
	 */
	private Socket socket = null;
	
	/**
	 * The transmit stream that will be stored to support persistent connections
	 */
	private DataOutputStream transmitStream = null;

	/**
	 * The port number for the socket
	 */
	private int portNumber;
	/**
	 * The constructor that sets the file location
	 * 
	 * @param file
	 *            The file that the user designated to save the file
	 */
	public ClientServerConnection(File file) {
		this.file = file;
	}
	
	public void setPortNumber(int portNumber) {
		this.portNumber = portNumber;
	}

	/**
	 * @return the file location
	 */
	public File getFile() {
		return this.file;
	}

	/**
	 * This method will make a request to the server using the information saved
	 * in the Request class.
	 * 
	 * This class will pass back a null Response if an error occurs in this
	 * method
	 * 
	 * @param request The request that the user is making
	 * @return The response that is received from the server
	 */
	public Response initialRequest(Request request) {
		Response response = null;
		try {
			socket = new Socket(request.getHostName(), this.portNumber);
			transmitStream = new DataOutputStream(socket.getOutputStream());
			
			response = followUpRequest(request);
			
		} catch (IOException e) {
			System.out.println("There was an error opening the socket\n");
			e.printStackTrace();
		}
		return response;
	}

	
	public Response followUpRequest(Request request){
		Response response = null;
		
		try {
			// Assuming the request.toString() is in the format of "GET " +
			// resourceID + "  HTTP/1.1" + CRLF + "Host: "
			// + hostName + CRLF + CRLF;
			transmitStream.writeBytes(request.toString());
			try {
				InputStream input = socket.getInputStream();
				response = new Response(input);
				File file = new File(this.file, response.getFileName());
				if(file.exists()){
					file.delete();
				}
				file.createNewFile(); //Should no longer throw exception - file name sometimes had a space at the end
				FileOutputStream fo = new FileOutputStream(file);
				
				// only read entity body if the status is 200 OK
				// otherwise the program will stall waiting for input that does not come
				if (response.getStatusLine().contains("200")){
					response.readEntityBody(fo);
				}
				
				fo.flush();
				fo.close();
			} catch (IOException e) {
				System.out
				.println("An error occured when trying to get the input stream from the socket\n");
				e.printStackTrace();
			}
		} catch (IOException e) {
			System.out
			.println("There was an error transmitting the request\n");
		}
		
		return response;
	}
	
	
	/**
	 * Closes the socket
	 */
	public void close() {
		try {
			socket.close();
		} catch (IOException e) {
			System.out.println("Error in closing the socket");
		}
	}

	/**
	 * A setter for the file location
	 * 
	 * @param the
	 *            file where the user wants to save to
	 */
	public void setFileLocation(File file) {
		this.file = file;
	}

}
